#include "mouse_painter_demo.hpp"
#include <iostream>
#include <QMouseEvent>
#include <QtMath>
#include <QAction>

MousePainterDemo::MousePainterDemo()
{
  std::cout << "create MousePainterDemo" << std::endl;
  this->setFixedSize(800, 600);
  this->setMouseTracking(true); // 开启鼠标追踪
  start_point_.setX(-1);
  start_point_.setY(-1);

  end_point_.setX(-1);
  end_point_.setY(-1);
  QAction* action_1 = new QAction(tr("线宽2"), this);
  QAction* action_2 = new QAction(tr("线宽4"), this);
  QAction* action_3 = new QAction(tr("线宽8"), this);
  this->addAction(action_1);
  this->addAction(action_2);
  this->addAction(action_3);
  this->setContextMenuPolicy(Qt::ActionsContextMenu);
  connect(action_1, SIGNAL(triggered()), this, SLOT(changeLine_W_2()));
  connect(action_2, SIGNAL(triggered()), this, SLOT(changeLine_W_4()));
  connect(action_3, SIGNAL(triggered()), this, SLOT(changeLine_W_8()));
}

void MousePainterDemo::changeLine_W_2()
{
  line_width_ = 2;
}

void MousePainterDemo::changeLine_W_4()
{
  line_width_ = 4;
}

void MousePainterDemo::changeLine_W_8()
{
  line_width_ = 8;
}

void MousePainterDemo::paintEvent(QPaintEvent *event)
{
  QPainter painter(this);
  painter.setRenderHint(QPainter::Antialiasing, true); // 抗锯齿
  painter.setPen(QColor(0, 0, 255));                   // 画笔颜色
  int cw = this->rect().width();
  int ch = this->rect().height();
  // 使用QPainter对象的fillRect函数来绘制一个矩形，并填充为透明色
  painter.fillRect(this->rect(), QColor(0, 0, 0));

  if (!this->pix_map_.isNull())
  {
    auto temp = pix_map_.scaled(QSize(800, 600), Qt::KeepAspectRatio);
    int iw = temp.width();
    int ih = temp.height();
    int shift_x = (cw - iw) / 2;
    int shift_y = (ch - ih) / 2;
    painter.drawImage(QRectF(shift_x, shift_y, iw, ih), temp.toImage());
  }
  QFont Font;
  Font.setPixelSize(36);
  painter.setFont(Font);
  painter.drawText(QPoint(100, 100), text_info_);

  QPen pen(Qt::green);
  pen.setWidth(4);
  pen.setColor(Qt::red);
  painter.setPen(pen);

  if (is_draw_)
  {
    pen.setStyle(Qt::SolidLine);
    painter.setPen(pen);
    switch (draw_type_)
    {
    case 1:
      painter.drawRect(QRectF(start_point_.x(), start_point_.y(), end_point_.x() - start_point_.x(), end_point_.y() - start_point_.y()));
      break;
    case 2:
      painter.drawEllipse(center, radius, radius);
      break;
    default:
      painter.drawLine(start_point_, end_point_);
      break;
    }
  }

  if (line_.p1().x() > 0 && line_.p1().y() > 0)
  {
    painter.drawLine(line_);
  }
  if (box.height() > 0 && box.width() > 0)
  {
    painter.drawRect(box);
  }
  if (this->center.x() > 0 && this->center.y() > 0 )
  {
    painter.drawEllipse(center, radius, radius);
  }
}

void MousePainterDemo::mousePressEvent(QMouseEvent *event)
{
  start_point_.setX(event->x());
  start_point_.setY(event->y());
  if (this->draw_type_ == 2)
  {
    center.setX(event->x());
    center.setY(event->y());
  }
  is_draw_ = true;
  if (this->draw_type_ == 1)
  {
    box.setTopLeft(QPoint(-1, -1));
    box.setBottomRight(QPoint(-1, -1));
  }
}

void MousePainterDemo::mouseReleaseEvent(QMouseEvent *event)
{
  if (this->is_draw_ && start_point_.x() != -1 && start_point_.y() != -1)
  {
    end_point_.setX(event->x());
    end_point_.setY(event->y());
    is_draw_ = false;
    if (draw_type_ == 0)
    {
      line_.setP1(QPoint(start_point_.x(), start_point_.y()));
      line_.setP2(QPoint(end_point_.x(), end_point_.y()));
    }
    else if (draw_type_ == 1)
    {
      box.setTopLeft(start_point_);
      box.setBottomRight(end_point_);
    }
    else if (draw_type_ == 2)
    {
      int dx = end_point_.x() - start_point_.x();
      int dy = end_point_.y() - start_point_.y();
      radius = sqrt(dx * dx + dy * dy);
    }

    start_point_.setX(-1);
    start_point_.setY(-1);

    end_point_.setX(-1);
    end_point_.setY(-1);
  }
  this->is_draw_ = false;
  this->repaint();
}

void MousePainterDemo::mouseDoubleClickEvent(QMouseEvent *event)
{
}

void MousePainterDemo::mouseMoveEvent(QMouseEvent *event)
{
  if (this->is_draw_ && start_point_.x() != -1 && start_point_.y() != -1)
  {
    end_point_.setX(event->x());
    end_point_.setY(event->y());
    if (this->draw_type_ == 2)
    {
      int dx = end_point_.x() - start_point_.x();
      int dy = end_point_.y() - start_point_.y();
      radius = sqrt(dx * dx + dy * dy);
    }
    this->repaint();
  }
}

void MousePainterDemo::setTextInfo(const QString &text)
{
  text_info_ = text;
  this->repaint();
}

void MousePainterDemo::setImage(const QPixmap &image)
{
  if (image.isNull())
  {
    std::cout << "Attempted to set null image\n";
    return;
  }
  pix_map_ = image;
  this->repaint();
}

void MousePainterDemo::setDrawType(int draw_type)
{
  draw_type_ = draw_type;
}
